package com.dlry.serviceImpl;

import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.dlry.db.BranchRepository;
import com.dlry.db.UserRepository;
import com.dlry.entity.DlBranch;
import com.dlry.entity.DlLeave;
import com.dlry.entity.DlLoginuser;
import com.dlry.entity.DlNotification;
import com.dlry.entity.DlTravelRequest;
import com.dlry.exception.UserNotFoundException;

@Service
@Transactional
public class UserServiceImpl implements UserService {

	@Autowired
	private UserRepository userRepository;
	@Autowired
	private BranchRepository branchRepository;
	private static final Logger logger = LogManager.getFormatterLogger(UserServiceImpl.class.getName());
	@Autowired
	private PasswordEncoder passwordEncoder;

	public UserServiceImpl() {
	}

	public UserServiceImpl(UserRepository userRepository) {
		this.userRepository = userRepository;
	}

	public void save(String userName, String password, String phoneNumber, String inEmail, String realName) {
		DlLoginuser user = new DlLoginuser();
		user.setName(userName);
		user.setPassword(passwordEncoder.encode(password));
		user.setPhoneNumber(phoneNumber);
		user.setInEmail(inEmail);
		user.setRealName(realName);
		userRepository.save(user);
		logger.info(userName + " user saved");
	}

	public void update(Long uId, String password, String phoneNumber, String inEmail, Boolean enabled,
			String realName) {
		DlLoginuser user = userRepository.findOne(uId);
		if (password != null) {
			user.setPassword(passwordEncoder.encode(password));
		}
		if (phoneNumber != null) {
			user.setPhoneNumber(phoneNumber);
		}
		if (inEmail != null) {
			user.setInEmail(inEmail);
		}
		if (enabled != null) {
			user.setEnabled(enabled);
		}
		userRepository.save(user);
		logger.info(user.getName() + " user updated");
	}

	public List<DlNotification> getNotificationsPagedById(Long uId, Integer page, Integer row) {
		List<DlNotification> notifications = userRepository.getNotificationsPagedById(uId, (page - 1) * row, row);
		return notifications;
	}

	public List<DlLeave> getLeavesPagedById(Long uId, Integer page, Integer row) {
		List<DlLeave> leaves = userRepository.getLeavesPagedById(uId, (page - 1) * row, row);
		return leaves;
	}

	public List<DlTravelRequest> getTravelRequestsPagedById(Long uId, Integer page, Integer row) {
		List<DlTravelRequest> requests = userRepository.getTravelPagedById(uId, (page - 1) * row, row);
		return requests;
	}

	public DlLoginuser findByName(String name) {

		return userRepository.findByName(name);
	}

	public DlLoginuser findOne(Long id) {
		return userRepository.findOne(id);
	}

	public Long getCountNotificationById(Long uId) {
		return userRepository.getNotificationCountById(uId);
	}

	public Long getCountTravelById(Long uId) {
		return userRepository.getTravelRequestCountById(uId);
	}

	public Long getCountLeaveById(Long uId) {
		return userRepository.getLeaveCountById(uId);
	}

	public void save(DlLoginuser user) throws Exception {
		String name = user.getName();
		DlLoginuser findUser = userRepository.findByName(name);
		if (findUser != null) {
			throw new  Exception("用户名已存在");
		}
		user.setPassword(passwordEncoder.encode(user.getPassword()));
		userRepository.save(user);
	}

	public void update(DlLoginuser user) {
		userRepository.save(user);
		logger.info(user.getName() + " user updated");
	}

	public void changeUserPassword(Long uId, String password) {
		userRepository.changeUserPassword(uId, passwordEncoder.encode(password));
	}

	public Page<DlLoginuser> findAll(Integer page, Integer rows) {
		Pageable pageable = new PageRequest(page, rows);
		return userRepository.findAll(pageable);
	}

	public DlLoginuser findSuperior(Long id) throws UserNotFoundException {
		DlLoginuser user = userRepository.findOne(id);
		return findSuperior(user);
	}

	public DlLoginuser findSuperior(DlLoginuser user) throws UserNotFoundException {
		DlLoginuser leader = null;
		int level = user.getLevel();
		DlBranch branch = user.getBranch();
		if (branch.getLevel() == 2) {
			throw new UserNotFoundException("没有更高级别的用户了");
		} else if (branch.getLevel() == 1) {
			if (level == 0) {
				leader = userRepository.getLeader(branch.getId());
			} else {
				leader = userRepository.getLeader(branchRepository.findOneByName("部长").getId());
			}
			return leader;
		}
		return null;
	}

	public List<String> findAllBranch() {
		return branchRepository.findAllName();
	}
}
